using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;

using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Reflection;

using SKYPE4COMLib;

namespace Skypiee.Core
{
    public class SkypieeCore
    {
        // Some flags to check our status information
        public bool Attached = false;
        public bool IsOnline = false;
        public bool WasAttached = false;
        public bool PendingSilentModeStartup = false;
        public bool ShowHandle = true;
        public bool ShowHardWiredGroups = false;

        public List<SkypieeUser> Contacts = new List<SkypieeUser>();
        public List<IGroup> Groups = new List<IGroup>();
        public List<ICall> ActiveCalls = new List<ICall>();
        public List<ICall> Calls = new List<ICall>();

        public ICall icall;
        public String CallInfo = "";
        public String LastCallTransferredId = "";

        // Uses the normal Skype4COMLib using statement
        public Skype skype = new Skype();

        // Use this for ambiguous reference situations like
        // Attachment Status, Connection Status and others
        public SKYPE4COMLib.SkypeClass cSkype;

        public SkypieeCore()
        {
            cSkype = new SkypeClass();
        }

        public void CheckSkype()
        {
            if (!skype.Client.IsRunning) skype.Client.Start(true, true);
        }

        public void Shutdown()
        {
            if (skype.Client.IsRunning) skype.Client.Shutdown();
        }

        public bool LoadAllContacts()
        {
            return LoadContacts(skype.HardwiredGroups[1]);
        }

        public bool LoadContacts(IGroup group)
        {
            return LoadContacts(group, false, true, true);
        }

        public bool LoadContacts(IGroup group, bool onlyOnline, bool skype, bool skypeOut)
        {
            UserCollection users = group.Users;

            Contacts.Clear();

            Console.WriteLine("  Users: {0}", users.Count);

            for (int j = 0; j < users.Count; j++)
            {
                IUser iuser = users[j + 1];

                if (onlyOnline)
                {
                    if (iuser.OnlineStatus == TOnlineStatus.olsOffline ||
                        iuser.OnlineStatus == TOnlineStatus.olsUnknown) continue;
                }

                if (skype && skypeOut)
                {
                    if (iuser.IsSkypeOutContact) continue;
                }
                else if (skype)
                {
                    if (iuser.IsSkypeOutContact) continue;
                }
                else if (skypeOut)
                {
                    if (!iuser.IsSkypeOutContact) continue;
                }

                SkypieeUser user = new SkypieeUser();

                user.IUser = iuser;
                user.DisplayName = iuser.DisplayName;
                user.Handle = iuser.Handle;
                user.FullName = iuser.FullName;

                user.AvatarPath = GetAvatar(iuser.Handle);

                Contacts.Add(user);
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userHandle"></param>
        /// <returns></returns>
        public string GetAvatar(string userHandle)
        {
            try
            {
                string temp = System.IO.Path.GetTempPath();
                string tempFile = string.Format("{0}\\s_{1}.jpg", temp, userHandle);

                try
                {
                    if (!File.Exists(tempFile))
                    {
                        SKYPE4COMLib.Command command = new SKYPE4COMLib.CommandClass();
                        command.Command = @"GET USER " + userHandle + " AVATAR 1 " + tempFile;
                        command.Blocking = false;
                        command.Id = (int)DateTime.Now.Ticks;

                        skype.SendCommand(command);
                    }
                }
                catch
                { 
                }


                return tempFile;
            }
            catch
            {
                return "";
            }
        }

        public string GetGroupTypeName(IGroup group)
        {
            return skype.Convert.GroupTypeToText(group.Type);
        }

        public void PlaceCall(string handle)
        {
            PlaceCall(handle, null, null, null);
        }

        public void PlaceCall(string handle1, string handle2, string handle3, string handle4)
        {
            Call call = skype.PlaceCall(handle1, handle2, handle3, handle4);

            icall = call;
        }

        public void FinishCall(ICall call)
        {
            call.Finish();
        }

        public bool LoadCalls()
        {
            Calls.Clear();
            ActiveCalls.Clear();

            for (int i = 0; i < skype.ActiveCalls.Count; i++)
            {
                ICall call = skype.ActiveCalls[i + 1];
                Calls.Add(call);

                if (call.Status == TCallStatus.clsInProgress
                    || call.Status == TCallStatus.clsLocalHold 
                    || call.Status ==  TCallStatus.clsRinging)
                {
                    ActiveCalls.Add(call);
                }
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool LoadGroups()
        {
            IGroup oGroup;

            Groups.Clear();

            try
            {
                if (skype.Groups.Count < 1)
                {
                    return false;
                }
            }
            catch (Exception)
            {
                
                return false;
            }

            Groups.Clear();

            if (ShowHardWiredGroups)
            {
                try
                {
                    for (int i = 0; i < skype.HardwiredGroups.Count; i++)
                    {
                        for (int j = 0; j < skype.Groups.Count; j++)
                        {
                            if (skype.Groups[j + 1].Id == skype.HardwiredGroups[i + 1].Id)
                            {
                                Groups.Add(skype.HardwiredGroups[i + 1]);
                                break;
                            }
                        }
                    }
                }
                catch (Exception)
                {                   
                    return false;
                }
            }
            else
            {
                try
                {
                    for (int i = 0; i < skype.Groups.Count; i++)
                    {
                        if ((skype.Groups[i + 1].Type == TGroupType.grpOnlineFriends) || (skype.Groups[i + 1].Type == TGroupType.grpSkypeOutFriends))
                        {
                            Groups.Add(skype.Groups[i + 1]);
                        }
                    }
                }
                catch (Exception)
                {
                    // All Skype Logic uses TRY for safety
                    return false;
                }
            }

            try
            {
                if (skype.CustomGroups.Count > 0)
                {
                    for (int i = 0; i < skype.CustomGroups.Count; i++)
                    {
                        for (int j = 0; j < skype.Groups.Count; j++)
                        {
                            if (skype.Groups[j + 1].Id == skype.CustomGroups[i + 1].Id)
                            {
                                oGroup = skype.Groups[j + 1];
                                Groups.Add(oGroup);
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                // All Skype Logic uses TRY for safety
            }

            return true;
        }

        
        public void Start()
        {
            cSkype.Attach(7, false);
        }

        public void End()
        {
            //cSkype
        }

    }
}
